package top.healthylife.gateway.platformchain.api.util;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import top.healthylife.basics.utils.exception.BusinessException;
import top.healthylife.basics.utils.utils.SystemThreadLocal;
import top.healthylife.gateway.platformchain.api.config.SystemConfig;
import top.heathylife.gateway.common.cons.SystemCons;
import top.heathylife.gateway.common.po.RecordRequestInfo;

import java.util.HashMap;
import java.util.Map;


/**
 * [Description] : 请求外部接口的http请求工具类
 *
 * @author : Gaozexi
 * @version : 1.0
 * @since : 2019-12-11 15:57
 */
@Slf4j
public class OutHttpUtil {
    public final static String BASE_URL = "http://qkl-api-dev.cguarantee.com";

    final static String SUCCESS = "0";
    final static String CODE = "code";
    final static String DATA = "data";
    final static String APP_CODE = "appCode";
    final static String NOT_DATA = "300000";
    public final static String[] TOKEN_WRONG = {"300002", "300003", "300005", "300006", "300007", "300008", "300009"};

    final static String ERROR_CODE = "error_code";

    public static final Map<String, String> ERROR_MAP = new HashMap<>();

    static {
        ERROR_MAP.put("300000", "无数据");
        ERROR_MAP.put("300001", "请求失败");
        ERROR_MAP.put("300002", "账号失效");
        ERROR_MAP.put("300003", "账号过期");
        ERROR_MAP.put("300004", "访问频率过快");
        ERROR_MAP.put("300005", "无权限访问此api");
        ERROR_MAP.put("300006", "余额不足");
        ERROR_MAP.put("300007", "剩余次数不足");
        ERROR_MAP.put("300008", "缺少必要参数");
        ERROR_MAP.put("300009", "账号信息有误");
        ERROR_MAP.put("300010", "URL不存在");
    }

    /**
     * 发送get请求
     *
     * @param url .
     * @return 响应json
     */
    @SneakyThrows
    public static <T> T get(String url, SystemConfig systemConfig, Class<T> cls) {
         String returnData = HttpUtil.get(url);
        return sendRequest(returnData, cls);
    }


    /**
     * 发送get请求
     *
     * @param url    .
     * @param params 参数
     * @return 响应json
     */
    @SneakyThrows
    public static <T> T post(String url, Map<String, Object> params, SystemConfig systemConfig, Class<T> cls) {
        // 使用config的aes秘钥加密入参,请求
        Map<String, Object> map = beforeRequest(params);
        //记录请求信息
        String body = JSONObject.toJSONString(map);
        RecordRequestInfo.recordRequest(url, body, null, "post");
        String returnData = HttpUtil.createPost(url).body(body).execute().body();
        //将三方元数据存储到线程变量
        SystemThreadLocal.set(SystemCons.ORIGIN_DATA,returnData);
        return sendRequest(returnData, cls);
    }

    private static <T> T sendRequest(String returnData, Class<T> cls) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(returnData);
            String code = jsonObject.getString(CODE);
            if (SUCCESS.equals(code)) {
                String appCode = jsonObject.getString(APP_CODE);
                try {
                    JSONObject data = jsonObject.getJSONObject(DATA);
                    if (data != null) {
                        data.put(APP_CODE,appCode);
                        return data.toJavaObject(cls);
                    }
                }catch (ClassCastException ex){
                    JSONArray jsonArray = jsonObject.getJSONArray(DATA);
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                        jsonObject1.put(APP_CODE,appCode);
                    }
                    JSONObject jsonObject1 = new JSONObject();
                    jsonObject1.put("data",jsonArray);
                    return jsonObject1.toJavaObject(cls);
                }

            }
            return cls.newInstance();
        } catch (Exception e) {
            log.error("请求接口响应异常",e);
            throw new BusinessException("请求接口响应异常");
        }
    }

    public static Map<String, Object> beforeRequest(Map<String, Object> map) {

        Object appCode = map.remove(APP_CODE);
        Map<String, Object> params = new HashMap<>(4);
        params.put(APP_CODE, appCode);
        params.put(DATA, map);
        return params;
    }
}
